/**
 * 
 */
package info.niwota.group.thread;

import info.niwota.group.Constants;
import info.niwota.group.R;
import info.niwota.group.thread.Topic.Threads;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.app.SearchManager;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.DialogInterface.OnClickListener;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.ContextMenu;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.Toast;

/**
 * @author qiangli
 * 
 */
public class TopicListActivity extends ListActivity implements android.view.View.OnClickListener {
	private static final String LAST_TOPIC_ID = "last.topic.id";

	// context menu
	private static final int MENU_DELETE = Menu.FIRST + 4;
	private static final int MENU_EDIT = Menu.FIRST + 3;
	private static final int MENU_VIEW = Menu.FIRST + 2;

	private static final String[] PROJECTION = { Threads._ID, Threads.NAME,
			Threads.EMAILS, Threads.TITLE, Threads.BODY, Threads.PHOTO,
			Threads.MODIFIED_DATE };

	private static final int RC_ADD = 2;
	private static final int RC_EDIT = 1;
	private static final int RC_VIEW = 3;

	private static final String TAG = "TopicListActivity";

	protected static final long TOPIC_ID_NONE = -1;

	private static long getLastId(Context context) {
		try {
			final SharedPreferences p = PreferenceManager
					.getDefaultSharedPreferences(context);
			return p.getLong(LAST_TOPIC_ID, TOPIC_ID_NONE);
		} catch (Exception e) {
		}
		return TOPIC_ID_NONE;
	}

	private static void putLastId(Context context, long id) {
		try {
			final SharedPreferences p = PreferenceManager
					.getDefaultSharedPreferences(context);
			p.edit().putLong(LAST_TOPIC_ID, id).commit();
		} catch (Exception e) {
		}
	}

	private SimpleCursorAdapter adapter;

	private long itemId;
	
	protected Cursor mCursor;
	
	private int position;

	private void checkItem(int pos) {
		ListView v = getListView();
		v.clearChoices();
		v.setItemChecked(pos, true);
	}

	protected void doAdd() {
		Intent i = new Intent(this, EditTopicActivity.class);
		i.setAction(Intent.ACTION_INSERT);
		//
		startActivityForResult(i, RC_ADD);
	}

	private void doDelete() {
		try {
			final Cursor c = mCursor;
			c.moveToPosition(position);

			final String name = c.getString(c
					.getColumnIndexOrThrow(Threads.NAME));
			final String title = getResources().getString(
					R.string.title_topic_delete, name);
			final String msg = getResources().getString(
					R.string.text_are_you_sure);
			new AlertDialog.Builder(this)
					.setTitle(title)
					.setMessage(msg)
					.setPositiveButton(R.string.button_confirm,
							new OnClickListener() {
								public void onClick(DialogInterface dialog,
										int arg1) {
									Uri topicUri = ContentUris.withAppendedId(
											Topic.ALL_TOPICS_URI, c.getInt(0));
									int del = getContentResolver().delete(
											topicUri, null, null);
									if (del > 0) {
										//
										restoreCheck();
										Toast.makeText(TopicListActivity.this,
												R.string.msg_topic_delete,
												Toast.LENGTH_SHORT).show();
									} else {
										Toast
												.makeText(
														TopicListActivity.this,
														getString(
																R.string.msg_topic_failed,
																name),
														Toast.LENGTH_SHORT)
												.show();
										if (Constants.DEBUG_ENABLED) {
											Log.d(TAG, "failed to delete: "
													+ topicUri);
										}
									}
								}
							}).setNegativeButton(R.string.button_cancel, null)
					.show();
		} catch (Exception e) {
			Toast.makeText(this,
					getString(R.string.msg_topic_failed, e.getMessage()),
					Toast.LENGTH_SHORT).show();
			// e.printStackTrace();
		}
	}

	private void doEdit() {
		Cursor c = mCursor;
		c.moveToPosition(position);
		//
		int id = c.getInt(c.getColumnIndexOrThrow(Threads._ID));
		String name = c.getString(c.getColumnIndexOrThrow(Threads.NAME));
		String t = c.getString(c.getColumnIndexOrThrow(Threads.TITLE));
		String b = c.getString(c.getColumnIndexOrThrow(Threads.BODY));
		String e = c.getString(c.getColumnIndexOrThrow(Threads.EMAILS));
		//
		Intent i = new Intent(this, EditTopicActivity.class);
		i.putExtra(Topic.EXTRA_ID, id);
		i.putExtra(Topic.EXTRA_NAME, name);
		i.putExtra(Topic.EXTRA_TITLE, t);
		i.putExtra(Topic.EXTRA_BODY, b);
		i.putExtra(Topic.EXTRA_EMAILS, e);
		//
		i.setAction(Intent.ACTION_EDIT);
		startActivityForResult(i, RC_EDIT);
	}

	private void doPostAdd(Intent data) {
		try {
			restoreCheck();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void doPostEdit(Intent data) {
		try {
			Cursor c = mCursor;
			c.requery();
			c.moveToPosition(position);
			//
			Uri topicUri = ContentUris.withAppendedId(Topic.ALL_TOPICS_URI, c
					.getInt(0));
			ContentValues values = new ContentValues();
			String name = data.getStringExtra(Topic.EXTRA_NAME);
			values.put(Threads.NAME, name);
			values.put(Threads.EMAILS, data.getStringExtra(Topic.EXTRA_EMAILS));
			values.put(Threads.TITLE, data.getStringExtra(Topic.EXTRA_TITLE));
			values.put(Threads.BODY, data.getStringExtra(Topic.EXTRA_BODY));
			values.put(Threads.MODIFIED_DATE, System.currentTimeMillis());
			getContentResolver().update(topicUri, values,
					"_id = " + c.getInt(0), null);
			//
			restoreCheck();
			Toast.makeText(this, R.string.msg_topic_edit, Toast.LENGTH_SHORT)
					.show();
		} catch (Exception e) {
			Toast.makeText(this,
					getString(R.string.msg_topic_failed, e.getMessage()),
					Toast.LENGTH_SHORT).show();
			// e.printStackTrace();
		}
	}

	private void doPostView() {
		//
	}

	private void doView() {
		Cursor c = mCursor;
		c.moveToPosition(position);
		//
		String name = c.getString(c.getColumnIndexOrThrow(Threads.NAME));
		String t = c.getString(c.getColumnIndexOrThrow(Threads.TITLE));
		String b = c.getString(c.getColumnIndexOrThrow(Threads.BODY));
		String e = c.getString(c.getColumnIndexOrThrow(Threads.EMAILS));
		//
		Intent i = new Intent(this, ViewTopicActivity.class);
		i.putExtra(Topic.EXTRA_NAME, name);
		i.putExtra(Topic.EXTRA_TITLE, t);
		i.putExtra(Topic.EXTRA_BODY, b);
		i.putExtra(Topic.EXTRA_EMAILS, e);
		//
		startActivityForResult(i, RC_VIEW);
	}

	private int findPositionById(long id, int def) {
		try {
			int cnt = adapter.getCount();
			for (int i = 0; i < cnt; i++) {
				long iid = adapter.getItemId(i);
				if (iid == id) {
					return i;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return def;
	}

	private void initCheck() {
		long id = getLastId(this);
		//
		Cursor c = mCursor;
		int cnt = c.getCount();
		if (cnt == 0) {
			updateTitle();
			return;
		}
		//
		int pos = findPositionById(id, 0);
		c.moveToPosition(pos);
		checkItem(pos);

		String name = c.getString(c.getColumnIndexOrThrow(Threads.NAME));
		updateTitle(name, cnt);
		itemId = c.getLong(c.getColumnIndexOrThrow(Threads._ID));
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (resultCode == RESULT_OK) {
			switch (requestCode) {
			case RC_EDIT:
				doPostEdit(data);
				break;
			case RC_ADD:
				doPostAdd(data);
				break;
			case RC_VIEW:
				doPostView();
				break;
			default:
			}
		}
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterView.AdapterContextMenuInfo mi = (AdapterView.AdapterContextMenuInfo) item
				.getMenuInfo();
		if (mi == null) {
			return true;
		}
		position = mi.position;
		//
		switch (item.getItemId()) {
		case MENU_VIEW:
			doView();
			break;
		case MENU_EDIT:
			doEdit();
			break;
		case MENU_DELETE:
			doDelete();
			break;
		default:
		}
		return true;
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		requestWindowFeature(Window.FEATURE_LEFT_ICON);
		setContentView(R.layout.topic_list);

		Intent intent = getIntent();
		Uri uri = null;
		String query = null;
		//
		if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
			query = intent.getStringExtra(SearchManager.QUERY);
		} else if (savedInstanceState != null) {
			query = savedInstanceState.getString(SearchManager.QUERY);
		}
		if (query != null && query.length() > 0) {
			uri = Uri.withAppendedPath(Topic.SEARCH_URI, Uri.encode(query));
		}
		if (uri == null) {
			// default (all topics)
			uri = Topic.ALL_TOPICS_URI;
		}

		// Do the query
		mCursor = managedQuery(uri, PROJECTION, null, null,
				Topic.DEFAULT_SORT_ORDER);

		// mHelper = new TopicHelper(this);
		//
		adapter = new SimpleCursorAdapter(this,
				R.layout.topic_list_item_single_choice, mCursor,
				new String[] { Threads.NAME }, new int[] { android.R.id.text1 });

		final ListView lv = getListView();
		lv.setAdapter(adapter);
		lv.setItemsCanFocus(false);
		lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
		lv.clearChoices();
		//
		int cnt = mCursor.getCount();
		//
		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "total notes: " + cnt);
		}
		//
		if (cnt <= 0) {
			// Log.d(TAG, "populating default greetings");
			// load
			// mCursor.requery();
		}
		//
		registerForContextMenu(lv);
		//
		getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
				R.drawable.icon25);
		//
		initCheck();
		//
		View buttons = findViewById(R.id.buttons);
		buttons.setVisibility(View.VISIBLE);
		TextView btnAdd = (TextView) findViewById(R.id.button_add);
		btnAdd.setOnClickListener(this);
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		menu.add(0, MENU_VIEW, 0, R.string.menu_view);
		menu.add(0, MENU_EDIT, 0, R.string.menu_edit);
		menu.add(0, MENU_DELETE, 0, R.string.menu_delete);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.topic_list_options, menu);
		return true;
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			setResult(RESULT_CANCELED);
			finish();
			return true;
		} else {
			return super.onKeyDown(keyCode, event);
		}
	}

	private void saveSelection(int pos) {
		try {
			Cursor c = mCursor;
			//
			long id = TOPIC_ID_NONE;
			String name = "";
			String title = "";
			String body = "";
			String emails = "";
			//int pos = findPositionById(itemId, -1);
			if (pos != -1) {
				c.moveToPosition(pos);
				id = c.getLong(c.getColumnIndexOrThrow(Threads._ID));
				name = c.getString(c.getColumnIndexOrThrow(Threads.NAME));
				title = c.getString(c.getColumnIndexOrThrow(Threads.TITLE));
				body = c.getString(c.getColumnIndexOrThrow(Threads.BODY));
				emails = c.getString(c.getColumnIndexOrThrow(Threads.EMAILS));
				//
				Intent data = new Intent();
				data.putExtra(Topic.EXTRA_NAME, name);
				data.putExtra(Topic.EXTRA_TITLE, title);
				data.putExtra(Topic.EXTRA_BODY, body);
				data.putExtra(Topic.EXTRA_EMAILS, emails);
				//
				setResult(RESULT_OK, data);
			} else {
				setResult(RESULT_CANCELED);
			}
			updatePreference(id);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		savePreference();
		//
		super.onSaveInstanceState(outState);
	}

	private void savePreference() {
		try {
			Cursor c = mCursor;
			//
			long id = TOPIC_ID_NONE;
			int pos = findPositionById(itemId, -1);
			if (pos != -1) {
				c.moveToPosition(pos);
				id = c.getLong(c.getColumnIndexOrThrow(Threads._ID));
				// name = c.getString(c.getColumnIndexOrThrow(Threads.NAME));
			}
			updatePreference(id);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	protected void onListItemClick(ListView list, View view, int pos, long id) {
		saveSelection(pos);
		finish();
		// Cursor c = mCursor;
		// c.moveToPosition(pos);
		// itemId = c.getLong(c.getColumnIndexOrThrow(Threads._ID));
		// String name = c.getString(c.getColumnIndexOrThrow(Threads.NAME));
		// updateTitle(name, c.getCount());
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		return false;
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		return false;
	}

	private void restoreCheck() {
		// restore the original checked item after destructive updates
		Cursor c = mCursor;
		c.requery();
		int cnt = c.getCount();
		if (cnt == 0) {
			updateTitle();
			itemId = TOPIC_ID_NONE;
			updatePreference(TOPIC_ID_NONE);
			return;
		}
		int pos = findPositionById(itemId, 0);
		// preference updated when BACK
		//
		checkItem(pos);
		c.moveToPosition(pos);
		String t = c.getString(c.getColumnIndexOrThrow(Threads.NAME));
		updateTitle(t, cnt);
		itemId = c.getLong(c.getColumnIndexOrThrow(Threads._ID));
	}

	protected void updatePreference(long id) {
		putLastId(this, id);
		// Preferences.putTopicSubject(this, subject);
		// Preferences.putTopicBody(this, body);
	}

	private void updateTitle() {
		setTitle(R.string.title_topic_threads_none);
	}

	protected void updateTitle(String title, int cnt) {
		if (cnt == 0) {
			setTitle(R.string.title_topic_threads_none);
			return;
		}
		String t = getString(R.string.title_topic_threads, cnt, title);
		setTitle(t);
	}

	public void onClick(View view) {
		switch (view.getId()) {
		case R.id.button_add:
			doAdd();
			break;
		default:
		}
	}
}
